#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "link_list.h"
//创建
LinkList* create_ll(void) {
    //分配内存
    LinkList* list = malloc(sizeof(LinkList));
    //初始化头尾指针
    list->head = NULL;
    list->tail = NULL;
    return list;
}
//判断表空
bool empty_ll(LinkList* list) {
    return list->head == NULL;
}
//添加节点
void add_head_ll(LinkList* list, void* data) {
    Node* node = create_n(data);
    //链表为空 新节点同时是头尾
    if (empty_ll(list)) {
        list->head = node;
        list->tail = node;
    }
    else {
        //链表不为空 新节点作为链表头 先插入然后成为新头部
        node->next = list->head;
        list->head = node;
    }
}

void add_tail_ll(LinkList* list, void* data) {
    Node* node = create_n(data);
    //链表为空 新节点同时是头尾
    if (empty_ll(list)) {
        list->head = node;
        list->tail = node;
    }
    else {
        //不为空 新节点成为新尾部节点 先插入然后成为新尾部
        list->tail->next = node;
        list->tail = node;
    }
}
//删除 头 尾 位置 值
bool del_head_ll(LinkList* list) {
    if (empty_ll(list)) return false;
    //备份头结点
    Node* tmp = list->head;
    //如果只有一个节点 直接清空
    if (list->head == list->tail) {
        list->head = NULL;
        list->tail = NULL;
    }
    else {
        //如果不止一个节点 那么表头变为下一节点
        list->head = tmp->next;
    }
    //释放备份的头结点
    free(tmp);
    return true;
}

bool del_tail_ll(LinkList* list) {
    if (empty_ll(list)) {
        return false;
    }
    //备份尾节点
    Node* tmp = list->tail;
    //如果只有一个节点则清空
    if (list->head == list->tail) {
        list->head = NULL;
        list->tail = NULL;
    }
    else {
        //如果不止一个节点 遍历到 尾节点的前一个节点 然后断开
        //前一个节点成为新的尾节点
        Node* prev = list->head;
        while (prev->next != tmp)
            prev = prev->next;
        prev->next = NULL;
        list->tail = prev;
    }
    //释放备份的原尾节点
    free(tmp);
    return true;
}

//销毁
void destory_ll(LinkList* list) {
    //链表不为空时连续删除头节点
    while (!empty_ll(list)) del_head_ll(list);
    // for(Node* node = list->head; node != NULL; node = node->next)free(node);
    //释放链表
    free(list);
}

bool del_index_ll(LinkList* list, int index) {
    if (empty_ll(list)) return false;
    Node* tmp = list->head;
    while (NULL != tmp->next && index > 1) {
        index--;
        tmp = tmp->next;
    }
    if (index == 1) return del_head_ll(list);
    if (NULL == tmp->next) return false;
    Node* prev = tmp->next;
    tmp->next = tmp->next->next;
    free(prev);
    return true;
}

bool del_val_ll(LinkList* list, void* key, CMP cmp) {
    if (empty_ll(list)) return false;
    Node* tmp = list->head;
    int index = 1;
    while (NULL != tmp->next && cmp(tmp->next->data, key))
    {
        index++;
        tmp = tmp->next;
    }
    return del_index_ll(list, index);
}
//查找
void* query_val_ll(LinkList* list, void* key, CMP cmp) {
    Node* n = list->head;
    while (n != NULL && cmp(n->data, key)) n = n->next;
    return n->data;
}
//访问
void* query_index_ll(LinkList* list, int index) {
    Node* n = list->head;
    while (index && NULL != n) {
        index--;
        n = n->next;
    }
    return n->data;
}
//修改
bool mod_index_ll(LinkList* list, int index, void* data) {
    Node* n = query_index_ll(list, index);
    if (NULL == n) return false;
    n->data = data;
    return true;
}
bool mod_val_ll(LinkList* list, void* old, void* new, CMP cmp) {
    Node* n = query_val_ll(list, old, cmp);
    if (NULL == n) return false;
    n->data = new;
    return true;
}
//长度
size_t size_ll(LinkList* list) {
    size_t cnt = 0;
    Node* n = list->head;
    while (NULL != n) {
        n = n->next;
        cnt++;
    }
    return cnt;
}
//遍历
void traversal_ll(LinkList* list, FUNC func) {
    for (Node* node = list->head; node != NULL; node = node->next) {
        func(node->data);
    }
}
